📌 Domain-Driven Design (DDD)
🌟 Introducción
Domain-Driven Design (DDD) busca alinear el sistema con el dominio que representa, permitiendo crear código robusto, flexible y mantenible.
Su objetivo principal es promover la escalabilidad y modularización, enfocándose en los conceptos clave, agregaciones y lógica de negocio.
🏗️ ¿Qué es DDD?
DDD es un enfoque de desarrollo de software que prioriza la lógica de negocio sobre la implementación tecnológica.
Se basa en dividir el sistema en Bounded Contexts, cada uno con responsabilidades bien definidas.
📌 Principios Claves de DDD
🛑 Bounded Context
Un Bounded Context es una área bien definida de la lógica de negocio con responsabilidades específicas y límites claros.
Cada contexto opera de manera autónoma y evita dependencias directas con otros contextos.
📦 Aggregates
Un Aggregate es una colección de entidades y objetos de valor que están relacionados dentro de un Bounded Context.
Garantiza la coherencia y encapsulación de reglas de negocio.
🧩 Entities & Value Objects
- Entities: Objetos con identidad única dentro de un contexto.
- Value Objects: Objetos sin identidad única, definidos solo por sus atributos.
📌 DDD y Micro Frontends
🚀 Implementación de DDD en un proyecto React con Micro Frontends
1️⃣ Identificar los Bounded Contexts
Utiliza DDD para dividir la aplicación en áreas independientes con límites claros.
Cada Bounded Context representa una funcionalidad bien definida y puede desarrollarse de forma aislada.
2️⃣ Crear Micro Frontends para cada Bounded Context
Cada Bounded Context se convierte en un Micro Frontend independiente.
Ejemplo de una plataforma de blogs:
- Content Management (Gestión de contenido)
- Creación y edición de posts
- Moderación de comentarios
- User Management (Gestión de usuarios)
- Autenticación
- Perfiles de usuario
3️⃣ Usar principios DDD para estructurar los Micro Frontends
Cada micro frontend debe mantener su propia lógica de negocio, sin depender de otros contextos.
Ejemplo:
- Gestión de contenido no debe depender directamente de Gestión de usuarios.
- La comunicación entre ellos se maneja mediante APIs bien definidas.
📌 📂 Estructura de Carpetas en React con DDD
📁 src/
├── 📁 apps/ # Micro frontends independientes
│ ├── 📁 auth/ # Módulo de autenticación
│ ├── 📁 projects/ # Módulo de proyectos
│ └── 📁 dashboard/ # Módulo de dashboard
│
├── 📁 services/ # Comunicación entre Bounded Contexts
│ ├── 📜 apiClient.ts
│ ├── 📜 authService.ts
│ ├── 📜 projectService.ts
│ ├── 📜 userService.ts
│ ├── 📜 dashboardService.ts # 🚀 Contexto Anticorrupción (ACL)
│
├── 📁 store/ # Estado global
│
├── 📁 hooks/ # Custom hooks
│
├── 📁 utils/ # Helpers
│
├── 📁 routes/ # Rutas
│
├── 📁 types/ # Definiciones de tipos (TypeScript)
│
└── 📜 index.tsx # Entrada de la app
📌 🛠️ Ejemplo de Integración: Dashboard de Proyectos
Si un dashboard de proyectos necesita mostrar qué usuarios participaron en cada proyecto, pero Usuarios y Proyectos son contextos separados, existen tres formas de integrarlos sin romper las reglas de independencia:
1️⃣ API Gateway (IDs en lugar de datos directos)
- En Proyectos se almacenan solo los IDs de los usuarios participantes.
- El frontend consulta la API de Usuarios con esos IDs.
2️⃣ Contexto Anticorrupción (ACL - Anti Corruption Layer)
- Se crea un servicio intermedio (
dashboardService.ts
) que consulta ambos contextos y unifica los datos.
📌 Ejemplo de código en dashboardService.ts
import { getUserById } from "./userService";
import { getProjectById } from "./projectService";
export const getDashboardData = async (projectId: string) => {
try {
const project = await getProjectById(projectId);
const userDetails = await Promise.all(
project.users.map((userId) => getUserById(userId))
);
return {
projectId: project.id,
projectName: project.name,
users: userDetails,
};
} catch (error) {
console.error("Error obteniendo datos del dashboard", error);
throw new Error("No se pudieron cargar los datos del dashboard");
}
};
3️⃣ Event-Driven Communication (Mensajes de Eventos)
- Cuando un usuario se une a un proyecto, se emite un evento asincrónico (
USER_JOINED_PROJECT
). - Usuarios escucha el evento y actualiza su base de datos local.
📌 📢 Buenas Prácticas en DDD
✅ Usar terminología consistente en todos los bounded contexts.
✅ Mantener límites claros entre bounded contexts para evitar dependencias innecesarias.
✅ Evitar consultas directas entre contextos, usar APIs bien definidas o eventos asincrónicos.
✅ Optimizar el rendimiento del dashboard con estrategias como cacheo o Contexto Anticorrupción
.
📌 🔥 Conclusión
DDD y Micro Frontends son una combinación poderosa para crear sistemas escalables y bien estructurados.